;;; init-company.el --- Company configuration -*- lexical-binding: t -*-
;;; Commentary:
;;; Code:

(add-hook 'after-init-hook 'global-company-mode)
(with-eval-after-load 'company
  (setq company-idle-delay   0.2
        company-global-modes '(not eshell-mode dired-mode shell-mode vterm-mode)
        company-minimum-prefix-length  1
        company-dabbrev-ignore-buffers "\\`[ *]\\|\\.pdf\\'")

  (setq company-backends'(company-capf
                          (company-dabbrev-code company-keywords)
                          company-files
                          company-dabbrev
                          company-yasnippet))

  ;; {{ Use number key select candidate
  (setq company-show-quick-access 'left)
  (setq company-quick-access-keys '("1." "2." "3." "4." "5." "6." "7." "8." "9." "0."))

  (defun my-company-number ()
    "Forward to `company-complete-number'.
Unless the number is potentially part of the candidate.
In that case, insert the number."
    (interactive)
    (let* ((k (this-command-keys))
           (re (concat "^" company-prefix k))
           (n (if (equal k "0") 10 (string-to-number k))))
      (cond
       ((or (cl-find-if (lambda (s) (string-match re s)) company-candidates)
            (> n (length company-candidates))
            (looking-back "[0-9]" (line-beginning-position)))
        (self-insert-command 1))
       (t
        (company-complete-number n)))))

  (let ((map company-active-map))
    (mapc
     (lambda (x)
       (define-key map (format "%d" x) 'my-company-number))
     (number-sequence 0 9)))
  ;; }}

  ;; {{ Sort company completions by use prescient.el
  (add-hook 'company-mode-hook 'company-prescient-mode)
  (setq company-prescient-sort-length-enable nil)
  ;; }}

  (define-key company-mode-map [remap indent-for-tab-command] #'company-indent-or-complete-common)
  (define-key company-mode-map [remap c-indent-line-or-region] #'company-indent-or-complete-common)
  (dolist (key (list [tab] (kbd "TAB") (kbd "C-n") (kbd "M-n")))
    (define-key company-active-map key #'company-complete-common-or-cycle))
  (dolist (key (list [backtab] (kbd "S-TAB") (kbd "C-k") (kbd "M-p")))
    (define-key-with-arg company-active-map key company-complete-common-or-cycle -1))
  (define-key company-active-map (kbd "M-/") #'company-other-backend)
  (define-key company-active-map (kbd "<escape>") #'company-abort))

(add-hook 'company-mode-hook 'company-posframe-mode)
(with-eval-after-load 'company-posframe
  (setq company-posframe-show-indicator nil)
  (setq company-posframe-show-metadata nil)
  (setq company-posframe-quickhelp-show-header nil))

(provide 'init-company)
;;; init-company.el ends here
